﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using System.Data.SqlClient;
using System.Net.Mail;
using System.IO;
using System.Configuration;
using System.Text.RegularExpressions;
using template_dll;
using System.Net;

namespace Sdata2WinService
{
    public partial class PharmMonitorServ : ServiceBase
    {
        private Timer aTimer;

        public PharmMonitorServ()
        {
            InitializeComponent();
            if (!EventLog.SourceExists("PharmMonitorServiceSource"))
            {
                EventLog.CreateEventSource("PharmMonitorServiceSource", "PharmMonitorServiceLog");
            }
            pharmMonitorEventLog.Source = "PharmMonitorServiceSource";
            pharmMonitorEventLog.Log = "PharmMonitorServiceLog";
        }

        protected override void OnStart(string[] args)
        {
            string evLog = "Запуск службы\n";
            evLog += "Запуск таймера";
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            int msec = Convert.ToInt32(config.AppSettings.Settings["TimerInteval"].Value) * 60000;
            aTimer = new Timer(msec);
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            aTimer.Enabled = true;
            if (aTimer.Enabled) evLog += "\nТаймер активен";
            else evLog += "\nТаймер не активен";

            pharmMonitorEventLog.WriteEntry(evLog);
        }

        protected override void OnStop()
        {
            pharmMonitorEventLog.WriteEntry("Остановка службы");
        }

        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            /*письма с мониторингом работы служб*/
            string evLog = "";
            SqlConnection con = new SqlConnection(@"Server=sdata2;Database=Competitors;Integrated Security=false;User ID=DDuanev;Password=19851007");
            SqlConnection conExchangeFilesDB = new SqlConnection(@"Server=sdata2;Database=ExchangeFilesDB;Integrated Security=false;User ID=DDuanev;Password=19851007");
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            try
            {
                int min = Convert.ToInt32(config.AppSettings.Settings["LastRespInteval"].Value);
                int msec = Convert.ToInt32(config.AppSettings.Settings["TimerInteval"].Value) * 60000;
                string emails = config.AppSettings.Settings["Email"].Value;
                aTimer.Interval = msec;

                SqlStorProc.sp_params[] par1 = new SqlStorProc.sp_params[1];
                par1[0].name = "@lastRespMinAgo";
                par1[0].value = min;
                DataTable dt = new SqlStorProc().SqlProcExecWithQueryOneTable(con, "sd2_PharmMonitor", 1200, par1);
                DataTable dtExchangeFilesDB = new SqlStorProc().SqlProcExecWithQueryOneTable(conExchangeFilesDB, "sd2_PharmMonitor", 1200, par1);

                if (dt.Rows.Count > 0)
                {
                    evLog += "Аптеки, у которых не откликается служба для парсинга сайтов более " + min + " мин. (возможно из-за проблем с интернетом)\n\n";
                    evLog += "Список аптек:\n\n";
                    foreach (DataRow row in dt.Rows)
                    {
                        evLog += row["Comment"] + ";\tIP: " + row["IPadds"] + ";\tКод МАП: " + row["PharmCode"] + ";\tПоследний отклик: " + Convert.ToDateTime(row["TimeLastResponse"]).ToString("HH:mm dd-MM-yyyy") + " (" + Convert.ToInt32(row["LastResponseMinuteAgo"]) + " мин. назад)\n";
                    }
                }

                if (dtExchangeFilesDB.Rows.Count > 0)
                {
                    if (dt.Rows.Count > 0) evLog += "\n\n";
                    evLog += "Аптеки, у которых не откликается служба для обмена файлами с офисом более " + min + " мин. (возможно из-за проблем с интернетом)\n\n";
                    evLog += "Список аптек:\n\n";
                    foreach (DataRow row in dtExchangeFilesDB.Rows)
                    {
                        evLog += row["Comment"] + ";\tIP: " + row["IPadds"] + ";\tКод МАП: " + row["PharmCode"] + ";\tПоследний отклик: " + Convert.ToDateTime(row["TimeLastResponse"]).ToString("HH:mm dd-MM-yyyy") + " (" + Convert.ToInt32(row["LastResponseMinuteAgo"]) + " мин. назад)\n";
                    }
                }

                if (dt.Rows.Count > 0 || dtExchangeFilesDB.Rows.Count > 0)
                    SendMail("192.168.0.9", "info_it@apteka-rayona.ru", "gk7qvw45", emails, "Мониторинг интернета в аптеках", evLog, null, false);
            }
            catch (Exception ex)
            {
                pharmMonitorEventLog.WriteEntry(ex.Message, EventLogEntryType.Error);
            }
            finally
            {
                con.Close();
                conExchangeFilesDB.Close();
                if (evLog != "") pharmMonitorEventLog.WriteEntry(evLog);
            }

            /*формирование файла monitor.csv*/
            TimeSpan now = DateTime.Now.TimeOfDay;
            if (now >= new TimeSpan(6, 0, 0) && now < new TimeSpan(7, 0, 0))
            {
                string monitor_mail = "Начало формирования файла monitor.csv: " + now.ToString("HH:mm:ss") + "\n";

                SqlConnection con_ = new SqlConnection(@"Server=sdata2;Database=PharmOLAPDW;Integrated Security=false;User ID=DDuanev;Password=19851007");
                try
                {
                    SqlStorProc.sp_params[] par = new SqlStorProc.sp_params[1];

                    par[0].name = "@datebal";
                    par[0].value = DateTime.Now.AddDays(-1).Date.ToString("yyyyMMdd"); //datatable
                    monitor_mail += "Получение данных с сервера...\n";
                    DataTable[] dt_rep = new DataTable[0];
                    try
                    {
                        dt_rep = new SqlStorProc().SqlProcExecWithQuery(con_, "pas_MonitorProd", 1200, par);
                        monitor_mail += "Данные получены: " + DateTime.Now.TimeOfDay.ToString("HH:mm:ss") + "\nНачало формирования файла...";
                    }
                    catch (Exception ex2)
                    {
                        monitor_mail += "ОШИБКА! Не удалось получить данные с сервера: " + DateTime.Now.TimeOfDay.ToString("HH:mm:ss") + "\n" + ex2.Message;
                    }
                    
                    if (dt_rep.Length == 2)
                    {
                        string fileName = config.AppSettings.Settings["ftpFileName"].Value.ToString();
                        if (File.Exists(fileName)) File.Delete(fileName);
                        if (SaveDGVToCSVfile(fileName, dt_rep[1]))
                        {
                            monitor_mail += "Файл сформирован: " + DateTime.Now.TimeOfDay.ToString("HH:mm:ss") + "\nПередача файла по FTP...";
                            try
                            {
                                FileInfo toUpload = new FileInfo(fileName);
                                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(config.AppSettings.Settings["ftpHost"].Value.ToString() + toUpload.Name);
                                request.Method = WebRequestMethods.Ftp.UploadFile;
                                request.Credentials = new NetworkCredential(config.AppSettings.Settings["ftpLog"].Value.ToString(), config.AppSettings.Settings["ftpPass"].Value.ToString());
                                Stream ftpStream = request.GetRequestStream();
                                FileStream fileStream = File.OpenRead(fileName);
                                byte[] buffer = new byte[1024];
                                int bytesRead = 0;
                                do
                                {
                                    bytesRead = fileStream.Read(buffer, 0, 1024);
                                    ftpStream.Write(buffer, 0, bytesRead);
                                }
                                while (bytesRead != 0);
                                fileStream.Close();
                                ftpStream.Close();
                                monitor_mail += "Файл отправлен по FTP: " + DateTime.Now.TimeOfDay.ToString("HH:mm:ss");
                                pharmMonitorEventLog.WriteEntry("Файл monitor.csv сформирован и залит на Ftp");
                            }
                            catch (Exception ex1)
                            {
                                monitor_mail += "ОШИБКА! Не удалось отправить файл по FTP: " + DateTime.Now.TimeOfDay.ToString("HH:mm:ss") + "\n" + ex1.Message;
                            }
                            if (File.Exists(fileName)) File.Delete(fileName);
                        }
                        else monitor_mail += "ОШИБКА! Не удалось сформировать файл: " + DateTime.Now.TimeOfDay.ToString("HH:mm:ss");
                    }
                }
                catch (Exception ex)
                {
                    pharmMonitorEventLog.WriteEntry("OnTimedEvent1\nОшибка при отправке файла на FTP" + ex.Message, EventLogEntryType.Error);
                }
                finally
                {
                    con_.Close();
                    SendMail("192.168.0.9", "info_it@apteka-rayona.ru", "gk7qvw45", config.AppSettings.Settings["ftpEmails"].Value.ToString(), "Формирование файла для сайта Ладушка", monitor_mail, null, false);
                }
            }
        }

        /// Отправка письма на почтовый ящик C# mail send
        /// <param name="smtpServer">Имя SMTP-сервера</param>
        /// <param name="from">Адрес отправителя</param>
        /// <param name="password">пароль к почтовому ящику отправителя</param>
        /// <param name="mailto">Адрес получателя</param>
        /// <param name="caption">Тема письма</param>
        /// <param name="message">Сообщение</param>
        /// <param name="attachFile">Присоединенный файл</param>
        private void SendMail(string smtpServer, string from, string password, string mailto, string caption, string message, string attachFile, bool del)
        {
            try
            {
                MailMessage mail = new MailMessage(from, mailto);
                //mail.From = new MailAddress(from);
                //string[] mailtoArr = Regex.Split(mailto, ";");
                //for (int i = 0; i < mailtoArr.Length; i++)
                //    mail.To.Add(new MailAddress(mailtoArr[i]));
                //mail.CC.Add(new MailAddress(from));
                mail.Subject = caption;
                mail.Body = message;
                if (!string.IsNullOrEmpty(attachFile))
                    mail.Attachments.Add(new Attachment(attachFile));
                SmtpClient client = new SmtpClient();
                client.Host = smtpServer;
                client.Port = 587;
                //client.Port = 25;
                client.UseDefaultCredentials = true;
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                client.Send(mail);
                mail.Dispose();
                if (!string.IsNullOrEmpty(attachFile) && del) File.Delete(attachFile);
            }
            catch (Exception ex)
            {
                pharmMonitorEventLog.WriteEntry(ex.ToString());
            }

        }

        /*формирование csv файла*/
        public bool SaveDGVToCSVfile(string filename, DataTable table)
        {
            try
            {
                StreamWriter sw = new StreamWriter(filename, false, Encoding.UTF8);

                List<int> col_n = new List<int>();
                foreach (DataColumn col in table.Columns)
                {
                    if (col.Ordinal < table.Columns.Count - 1) sw.Write(col.ColumnName + ";");
                    else sw.Write(col.ColumnName);
                    col_n.Add(col.Ordinal);
                }
                sw.WriteLine();
                int x = table.Rows.Count;

                for (int i = 0; i < x; i++)
                {
                    for (int y = 0; y < col_n.Count; y++)
                        if (y < col_n.Count - 1)
                            sw.Write(table.Rows[i][col_n[y]] + ";");
                        else sw.Write(table.Rows[i][col_n[y]]);
                    sw.Write("\r\n");
                }
                sw.Flush();
                sw.Close();
            }
            catch (Exception ex)
            {
                pharmMonitorEventLog.WriteEntry("SaveDGVToCSVfile\nОшибка при формировании файла Monitor.csv" + ex.Message, EventLogEntryType.Error);
                return false;
            }

            return true;
        }
    }
}
